package daer;

import java.io.*;
import java.text.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Recode {
    Date date;
    int month;
    double amount;
    String category;
    String note;

    /**
     * @param date 日期
     * @param month 月份
     * @param amount 金额
     * @param category 类别
     * @param note 备注
     */
    public Recode(Date date, int month, double amount, String category, String note) {
        this.date = date;
        this.month = month;
        this.amount = amount;
        this.category = category;
        this.note = note;
    }
}

public class PersonalFinance {
    private static Scanner scanner = new Scanner(System.in);

    // 文件路径
    private static final String IPATH = "D:\\Git_study\\PersonalFinance\\income.txt";
    private static final String EPATH = "D:\\Git_study\\PersonalFinance\\expense.txt";
    private static final String BPATH = "D:\\Git_study\\PersonalFinance\\budget.txt";

    public static void main(String[] args) {
        while (true) {
            Menu();
            int choice = Choice();
            switch (choice) {
                case 1:
                    Income();
                    break;
                case 2:
                    Expense();
                    break;
                case 3:
                    AllRecords();
                    break;
                case 4:
                    Query();
                    break;
                case 5:
                    SetBudget();
                    break;
                case 6:
                    MonthlyReport();
                    break;
                case 7:
                    System.out.println("已退出个人账单管理系统");
                    return;
                default:
                    System.out.println("无效选项，请重新输入。");
            }
        }
    }

    private static void Menu() {
        System.out.println("=================================");
        System.out.println("欢迎使用个人账单管理系统");
        System.out.println("=================================");
        System.out.println("请选择操作：");
        System.out.println("1. 记录收入");
        System.out.println("2. 记录支出");
        System.out.println("3. 查看所有账单");
        System.out.println("4. 查询账单");
        System.out.println("5. 设置月度预算");
        System.out.println("6. 查看月度统计报告");
        System.out.println("7. 退出系统");
    }

    private static int Choice() {
        System.out.print("请输入选项序号：");
        while (!scanner.hasNextInt()) {
            System.out.println("无效输入，请输入数字选项。");
            scanner.next();
            System.out.print("请输入选项序号：");
        }
        return scanner.nextInt();
    }

    // 记录收入
    private static void Income() {
        System.out.println("=================================");
        System.out.println("请输入收入信息：");
        Date date = getDate();
        int month = getMonth(date);
        double amount = getAmount("收入");
        System.out.print("类别（如工资、奖金等）：");
        String category = scanner.next();
        scanner.nextLine();
        System.out.print("备注：");
        String note = scanner.nextLine();

        // 将收入记录写入文件
        try (FileWriter incomeWriter = new FileWriter(IPATH, true)) {
            incomeWriter.write(new SimpleDateFormat("yyyy-MM-dd").format(date) + "," +
                    month + "," +
                    amount + "," +
                    category + "," +
                    note + "\n");
            System.out.println("收入已成功记录！");
        } catch (IOException e) {
            System.out.println("保存收入记录时发生错误: " + e.getMessage());
        }
        System.out.println("按任意键返回主菜单...");
        scanner.nextLine();
    }

    // 记录支出
    private static void Expense() {
        System.out.println("=================================");
        System.out.println("请输入支出信息：");
        Date date = getDate();
        int month = getMonth(date);
        double amount = getAmount("支出");

        // 检查当前月份的支出是否超过收入
        if (isExpenseExceedsIncome(month, amount)) {
            System.out.println("支出金额不能超过当前月份的收入总额！");
            System.out.println("按任意键返回主菜单...");
            scanner.nextLine();
            return;
        }

        System.out.print("类别（如餐饮、交通、购物等）：");
        String category = scanner.next();
        scanner.nextLine(); // consume newline
        System.out.print("备注：");
        String note = scanner.nextLine();

        // 将支出记录写入文件
        try (FileWriter expenseWriter = new FileWriter(EPATH, true)) {
            expenseWriter.write(new SimpleDateFormat("yyyy-MM-dd").format(date) + "," +
                    month + "," +
                    amount + "," +
                    category + "," +
                    note + "\n");
            System.out.println("支出已成功记录！");
        } catch (IOException e) {
            System.out.println("保存支出记录时发生错误: " + e.getMessage());
        }
        System.out.println("按任意键返回主菜单...");
        scanner.nextLine();
    }

    // 查看所有账单
    private static void AllRecords() {
        System.out.println("=================================");
        System.out.println("所有收入记录：");
        try (Scanner incomeScanner = new Scanner(new File(IPATH))) {
            while (incomeScanner.hasNextLine()) {
                String[] parts = incomeScanner.nextLine().split(",");
                System.out.println("日期: " + parts[0] +
                        ", 金额: " + parts[2] +
                        ", 类别: " + parts[3] +
                        ", 备注: " + parts[4]);
            }
        } catch (FileNotFoundException e) {
            System.out.println("暂无收入记录。");
        }

        System.out.println("所有支出记录：");
        try (Scanner expenseScanner = new Scanner(new File(EPATH))) {
            while (expenseScanner.hasNextLine()) {
                String[] parts = expenseScanner.nextLine().split(",");
                System.out.println("日期: " + parts[0] +
                        ", 金额: " + parts[2] +
                        ", 类别: " + parts[3] +
                        ", 备注: " + parts[4]);
            }
        } catch (FileNotFoundException e) {
            System.out.println("暂无支出记录。");
        }
        System.out.println("按任意键返回主菜单...");
        scanner.nextLine();
    }

    // 查询账单
    private static void Query() {
        System.out.println("=================================");
        System.out.println("请输入查询的日期范围（YYYY-MM-DD 到 YYYY-MM-DD）：");
        System.out.print("开始");
        Date start = getDate();
        System.out.print("结束");
        Date end = getDate();
        System.out.println("查询结果：");
        System.out.println("收入记录：");
        try (Scanner incomeScanner = new Scanner(new File(IPATH))) {
            boolean hasIncome = false;
            while (incomeScanner.hasNextLine()) {
                String[] parts = incomeScanner.nextLine().split(",");
                try {
                    Date date = new SimpleDateFormat("yyyy-MM-dd").parse(parts[0]);
                    if (date.compareTo(start) >= 0 && date.compareTo(end) <= 0) {
                        System.out.println("日期: " + parts[0] +
                                ", 金额: " + parts[2] +
                                ", 类别: " + parts[3] +
                                ", 备注: " + parts[4]);
                        hasIncome = true;
                    }
                } catch (ParseException e) {
                    System.out.println("解析日期时发生错误: " + e.getMessage());
                }
            }
            if (!hasIncome) {
                System.out.println("该日期范围内无收入记录。");
            }
        } catch (FileNotFoundException e) {
            System.out.println("暂无收入记录。");
        }

        System.out.println("支出记录：");
        try (Scanner expenseScanner = new Scanner(new File(EPATH))) {
            boolean hasExpense = false;
            while (expenseScanner.hasNextLine()) {
                String[] parts = expenseScanner.nextLine().split(",");
                try {
                    Date date = new SimpleDateFormat("yyyy-MM-dd").parse(parts[0]);
                    if (date.compareTo(start) >= 0 && date.compareTo(end) <= 0) {
                        System.out.println("日期: " + parts[0] +
                                ", 金额: " + parts[2] +
                                ", 类别: " + parts[3] +
                                ", 备注: " + parts[4]);
                        hasExpense = true;
                    }
                } catch (ParseException e) {
                    System.out.println("解析日期时发生错误: " + e.getMessage());
                }
            }
            if (!hasExpense) {
                System.out.println("该日期范围内无支出记录。");
            }
        } catch (FileNotFoundException e) {
            System.out.println("暂无支出记录。");
        }
        System.out.println("按任意键返回主菜单...");
        scanner.nextLine();
    }

    // 设置月度预算
    private static void SetBudget() {
        System.out.println("=================================");
        int month = getMonth(null); // 从用户输入中获取月份
        System.out.println("请输入月度预算金额：");
        double budget = getAmount("预算");

        // 将预算写入文件
        try (FileWriter budgetWriter = new FileWriter(BPATH, true)) {
            budgetWriter.write(month + "," + budget + "\n");
            System.out.println("月度预算已设置为：" + budget + "（" + month + "月）");
        } catch (IOException e) {
            System.out.println("保存预算时发生错误: " + e.getMessage());
        }
        System.out.println("按任意键返回主菜单...");
        scanner.nextLine();
    }

    // 查看月度统计报告
    private static void MonthlyReport() {
        System.out.println("=================================");
        int month = getMonth(null);
        System.out.println("月度统计报告（" + month + "月）：");
        double totalIncome = 0;
        double totalExpense = 0;
        Map<String, Double> iCategories = new HashMap<>();
        Map<String, Double> eCategories = new HashMap<>();

        // 统计指定月份的收入
        try (Scanner incomeScanner = new Scanner(new File(IPATH))) {
            while (incomeScanner.hasNextLine()) {
                String[] parts = incomeScanner.nextLine().split(",");
                int recordMonth = Integer.parseInt(parts[1]);
                if (recordMonth == month) {
                    totalIncome += Double.parseDouble(parts[2]);
                    iCategories.put(parts[3], iCategories.getOrDefault(parts[3], 0.0) + Double.parseDouble(parts[2]));
                }
            }
        } catch (FileNotFoundException e) {
            System.out.println("暂无收入记录。");
        }

        // 统计指定月份的支出
        try (Scanner expenseScanner = new Scanner(new File(EPATH))) {
            while (expenseScanner.hasNextLine()) {
                String[] parts = expenseScanner.nextLine().split(",");
                int recordMonth = Integer.parseInt(parts[1]);
                if (recordMonth == month) {
                    totalExpense += Double.parseDouble(parts[2]);
                    eCategories.put(parts[3], eCategories.getOrDefault(parts[3], 0.0) + Double.parseDouble(parts[2]));
                }
            }
        } catch (FileNotFoundException e) {
            System.out.println("暂无支出记录。");
        }

        System.out.println("总收入: " + totalIncome);
        System.out.println("收入类别统计：");
        for (Map.Entry<String, Double> entry : iCategories.entrySet()) {
            System.out.println("类别: " + entry.getKey() + ", 金额: " + entry.getValue());
        }

        System.out.println("总支出: " + totalExpense);
        System.out.println("支出类别统计：");
        for (Map.Entry<String, Double> entry : eCategories.entrySet()) {
            System.out.println("类别: " + entry.getKey() + ", 金额: " + entry.getValue());
        }

        // 获取指定月份的预算
        double budget = 0.0;
        try (Scanner budgetScanner = new Scanner(new File(BPATH))) {
            while (budgetScanner.hasNextLine()) {
                String[] parts = budgetScanner.nextLine().split(",");
                if (Integer.parseInt(parts[0]) == month) {
                    budget = Double.parseDouble(parts[1]);
                }
            }
        } catch (FileNotFoundException e) {
            System.out.println("暂无预算记录。");
        }

        double remainingBudget = budget - totalExpense;
        System.out.println("当前剩余预算: " + remainingBudget);
        System.out.println("按任意键返回主菜单...");
        scanner.nextLine();
    }

    private static Date getDate() {
        while (true) {
            System.out.print("日期（YYYY-MM-DD）：");
            String date = scanner.next();
            Pattern pattern = Pattern.compile("^\\d{4}-\\d{2}-\\d{2}$");
            Matcher matcher = pattern.matcher(date);
            if (matcher.matches()) {
                try {
                    return new SimpleDateFormat("yyyy-MM-dd").parse(date);
                } catch (ParseException e) {
                    System.out.println("日期无效，请输入有效的日期（YYYY-MM-DD）。");
                }
            } else {
                System.out.println("日期格式无效，请使用YYYY-MM-DD格式。");
            }
        }
    }

    private static double getAmount(String type) {
        while (true) {
            System.out.print("金额：");
            if (!scanner.hasNextDouble()) {
                System.out.println("金额必须是数字");
                scanner.next();
                continue;
            }
            double amount = scanner.nextDouble();
            if (amount <= 0) {
                System.out.println(type + "金额必须大于0");
            } else {
                return amount;
            }
        }
    }

    // 获取月份（从日期或用户输入）
    private static int getMonth(Date date) {
        if (date != null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            return calendar.get(Calendar.MONTH) + 1; // 月份从 1 开始
        } else {
            while (true) {
                System.out.print("请输入月份（1-12）：");
                if (!scanner.hasNextInt()) {
                    System.out.println("无效输入，请输入数字（1-12）。");
                    scanner.next();
                    continue;
                }
                int month = scanner.nextInt();
                if (month < 1 || month > 12) {
                    System.out.println("月份必须在 1 到 12 之间。");
                } else {
                    return month;
                }
            }
        }
    }

    // 检查当前月份的支出是否超过收入
    private static boolean isExpenseExceedsIncome(int month, double expenseAmount) {
        double totalIncome = 0;
        double totalExpense = 0;

        // 读取收入文件
        try (Scanner incomeScanner = new Scanner(new File(IPATH))) {
            while (incomeScanner.hasNextLine()) {
                String[] parts = incomeScanner.nextLine().split(",");
                int recordMonth = Integer.parseInt(parts[1]);
                if (recordMonth == month) {
                    totalIncome += Double.parseDouble(parts[2]);
                }
            }
        } catch (FileNotFoundException e) {
            System.out.println("暂无收入记录。");
        }

        // 读取支出文件
        try (Scanner expenseScanner = new Scanner(new File(EPATH))) {
            while (expenseScanner.hasNextLine()) {
                String[] parts = expenseScanner.nextLine().split(",");
                int recordMonth = Integer.parseInt(parts[1]);
                if (recordMonth == month) {
                    totalExpense += Double.parseDouble(parts[2]);
                }
            }
        } catch (FileNotFoundException e) {
            System.out.println("暂无支出记录。");
        }

        return totalExpense + expenseAmount > totalIncome;
    }
}